package org.budo.poi.util;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.budo.poi.csv.CSVWorkbook;
import org.budo.poi.doc.DocWorkbook;
import org.budo.poi.docx.DocxWorkbook;
import org.budo.poi.pdf.PdfWorkbook;
import org.budo.support.lang.util.ReflectUtil;
import org.budo.support.lang.util.StringUtil;

import lombok.extern.slf4j.Slf4j;

/**
 * Workbook 文档工具
 * 
 * @author li
 * @version 1 (2015年10月27日 下午2:27:14)
 * @since Java7
 */
@Slf4j
public class WorkbookUtil {
    public static void write(Workbook workbook, OutputStream outputStream) {
        try {
            workbook.write(outputStream);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    public static InputStream toInputStream(Workbook workbook) {
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        write(workbook, byteArrayOutputStream);
        return new ByteArrayInputStream(byteArrayOutputStream.toByteArray());
    }

    /**
     * HSSFWorkbook
     */
    public static Workbook newWorkbook(InputStream inputStream) {
        try {
            return new HSSFWorkbook(inputStream);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    public static Workbook xssfWorkbook(InputStream inputStream) {
        try {
            return new XSSFWorkbook(inputStream);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    public static String getSuffix(Workbook workbook) {
        if (workbook instanceof XSSFWorkbook) {
            return "xlsx";
        }

        if (workbook instanceof CSVWorkbook) {
            return "csv";
        }

        if (workbook instanceof HSSFWorkbook) {
            return "xls";
        }

        if (workbook instanceof PdfWorkbook) {
            return "pdf";
        }

        if (workbook instanceof DocWorkbook) {
            return "doc";
        }

        if (workbook instanceof DocxWorkbook) {
            return "docx";
        }

        throw new RuntimeException("#57 workbook=" + workbook);
    }

    public static String contentType(Workbook workbook) {
        if (workbook instanceof XSSFWorkbook) {
            return "application/octet-stream;charset=ISO8859-1";
        }

        if (workbook instanceof HSSFWorkbook) {
            return "application/octet-stream;charset=ISO8859-1";
        }

        if (workbook instanceof CSVWorkbook) {
            return "text/csv;charset=UTF-8";
        }

        if (workbook instanceof PdfWorkbook) {
            return "application/octet-stream";
        }

        if (workbook instanceof DocWorkbook) {
            return "application/octet-stream";
        }

        if (workbook instanceof DocxWorkbook) {
            return "application/octet-stream";
        }

        throw new RuntimeException("#57 workbook=" + workbook);
    }

    public static String getCellValueByParameterCell(Workbook workbook, String sheetName, Integer parameterCellNumber, String parameterCellValue, Integer resultCellNumber) {
        if (null == workbook || null == sheetName || null == parameterCellNumber || null == parameterCellValue || null == resultCellNumber) {
            log.error("#110 workbook=" + workbook + ", sheetName=" + sheetName + ", parameterCellNumber=" + parameterCellNumber //
                    + ", parameterCellValue=" + parameterCellValue + ", resultCellNumber=" + resultCellNumber);
            return null;
        }

        Sheet sheet = workbook.getSheet(sheetName);

        int lastRowNum = sheet.getLastRowNum();
        for (int rownum = 0; rownum < lastRowNum; rownum++) {
            Row row = sheet.getRow(rownum);
            String cellValueString = RowUtil.getCellValueString(row, parameterCellNumber);

            if (StringUtil.equals(cellValueString, parameterCellValue)) {
                return RowUtil.getCellValueString(row, resultCellNumber);
            }
        }

        log.error("#131 workbook=" + workbook + ", sheetName=" + sheetName + ", parameterCellNumber=" + parameterCellNumber + ", parameterCellValue=" + parameterCellValue + ", resultCellNumber=" + resultCellNumber);
        return null;
    }

    public static void close(Workbook workbook) {
        try {
            Class<?> targetType = workbook.getClass();
            String methodName = "close";
            Class[] parameterTypes = new Class[0];

            if (ReflectUtil.hasMethod(targetType, methodName, parameterTypes)) {
                ReflectUtil.invokeMethod(targetType, methodName, parameterTypes, workbook, new Object[0]);
            }

            // workbook.close(); 3 版本没有这个方法
        } catch (Throwable e) {
            throw new RuntimeException(e);
        }
    }
}